package com.guit.hrms.mapper;

import com.guit.hrms.dto.LocationCheckInDTO;
import com.guit.hrms.dto.SetCheckInTimeDTO;
import com.guit.hrms.po.AttendanceStatistics;
import com.guit.hrms.po.EmpSign;
import com.guit.hrms.po.Transaction;
import com.guit.hrms.vo.EmpSignVO;
import com.guit.hrms.vo.TransactionVO;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.util.List;

@Mapper
public interface AttendanceMapper {
    /**
     * 设置打卡时间
     * 在该部门没有设置打卡时间时，在总体设置表中新增该部门的打卡时间记录
     * @param setCheckInTimeDTO 设置打卡时间的信息
     * @return Integer 1成功，0失败
     */
    @Insert("insert into all_set (set_dept_id,set_dept_type,set_start_date,set_end_date,set_start_time,set_end_time) values (#{setDeptId},#{setDeptType},#{setStartDate},#{setEndDate},#{setStartTime},#{setEndTime})")
    Integer addCheckInTime(SetCheckInTimeDTO setCheckInTimeDTO);

    /**
     * 更新打卡时间
     * 在该部门原先有设置打卡时间时，在总体设置表中更新该部门的打卡时间记录
     * @param setCheckInTimeDTO 设置打卡时间的信息
     * @return Integer 1成功，0失败
     */
    @Update("update all_set set set_start_date = #{setStartDate},set_end_date = #{setEndDate},set_start_time = #{setStartTime},set_end_time = #{setEndTime} where set_dept_id = #{setDeptId}  and set_dept_type = #{setDeptType}")
    Integer updateCheckInTime(SetCheckInTimeDTO setCheckInTimeDTO);

    /**
     * 通过部门id获取对应的打卡日期时间
     * @param deptId 部门id
     * @return SetCheckInTimeDTO
     */
    @Select("select * from all_set where set_dept_id = #{deptId} and set_dept_type = #{deptType}")
    SetCheckInTimeDTO getCheckInTime(Integer deptId, Integer deptType);

    /**
     * 打卡记录
     * 在员工上班打卡时，在员工签到表中加入该员工的打卡日期与时间
     * @param locationCheckInDTO 定位打卡的信息
     * @return Integer 1成功，0失败
     */
    @Insert("insert into emp_sign (employee_id,on_work_time,check_in_date,check_in_status) values (#{employeeId},#{onWorkTime},#{checkInDate},1)")
    Integer locationCheckIn(LocationCheckInDTO locationCheckInDTO);

    /**
     * 打卡记录1
     * 在员工上班打卡时，在员工签到表中更新该员工的打卡时间，签到状态
     * @param locationCheckInDTO 定位打卡的信息
     * @return Integer 1成功，0失败
     */
    @Update("update emp_sign set on_work_time = #{onWorkTime}, check_in_status = 1 where employee_id = #{employeeId} and check_in_date = #{checkInDate}")
    Integer locationCheckIn1(LocationCheckInDTO locationCheckInDTO);

    /**
     * 打卡记录2
     * 在员工下班打卡时，在员工签到表中更新该员工的打卡时间，当天上班时间，当天加班时间，是否签到，签到状态
     * @param locationCheckInDTO 定位打卡的信息
     * @return Integer 1成功，0失败
     */
    Integer locationCheckIn2(LocationCheckInDTO locationCheckInDTO);

    /**
     * 查询对应员工当天是否有特殊情况
     * @param locationCheckInDTO 定位打卡的信息
     * @return Integer 1成功，0失败
     */
    @Select("select count(*) from emp_sign where employee_id = #{employeeId} and check_in_date = #{checkInDate} and circumstance != 1")
    Integer selectSign(LocationCheckInDTO locationCheckInDTO);

    /**
     * 打卡记录3
     * 在员工有特殊情况上班打卡时，在员工签到表中更新该员工的打卡时间
     * @param locationCheckInDTO 定位打卡的信息
     * @return Integer 1成功，0失败
     */
    @Update("update emp_sign set on_work_time = #{onWorkTime},check_in_status=1 where employee_id = #{employeeId} and check_in_date = #{checkInDate}")
    Integer locationCheckIn3(LocationCheckInDTO locationCheckInDTO);

    /**
     * 根据员工号和打卡日期查询考勤记录
     * @param locationCheckInDTO 定位考勤信息
     * @return Integer 1存在，0不存在
     */
    @Select("select * from emp_sign where employee_id = #{employeeId} and check_in_date = #{checkInDate}")
    LocationCheckInDTO getById(LocationCheckInDTO locationCheckInDTO);

    /**
     * 查询员工所在部门的打卡标准
     */
    @Select("select * from all_set where set_dept_id = #{deptId} and set_dept_type = #{deptType}")
    SetCheckInTimeDTO getTimeById(Integer deptId, Integer deptType);

    /**
     * 获取所有考勤信息
     * @return 所有考勤信息
     */
//    @Select("select * from emp_sign")
    List<EmpSign> getRecords(LocalDate checkInDate, Integer isCheckIn, Integer checkInStatus, Integer circumstance);

    /**
     * 获取单个员工考勤记录
     * @return 单个员工考勤记录
     */
    @Select("select * from emp_sign where employee_id = #{employeeId}")
    List<EmpSign> getRecordsById(String employeeId);

    /**
     * 事务申请
     * @param transaction 事务申请信息
     */

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into transaction(employee_id,employee_name,dept_id,dept_name,type,reason, start_time, end_time, apply_time)" +
            " values (#{employeeId}, #{employeeName}, #{deptId}, #{deptName},#{type},#{reason}, #{startTime}, #{endTime}, #{applyTime})")
    void affairs(Transaction transaction);

    /**
     * 个人查看事务表
     * @return 事务表
     */
//    @Select("select * from transaction where employee_id = #{employeeId}")
    List<TransactionVO> getTransactionById(Transaction transaction);

    /**
     * 根据主键id查询事务记录
     * @param id 主键id
     * @return 事务记录
     */
    @Select("select * from transaction where id=#{id}")
    TransactionVO getTransactionById2(Integer id);

    /**
     * 根据主键id查询事务记录
     * @param id 主键id
     * @return 事务记录
     */
    @Select("select * from transaction where id=#{id}")
    Transaction getTransactionById3(Integer id);

    /**
     * 删除事务记录
     * @param employeeId 员工id
     * @param ids 事务记录id
     */
    void deleteTransactionByIds(String employeeId, List<Integer> ids);

    /**
     * 销假
     * @param transaction 事务记录
     * @return Integer 1成功，0失败
     */
    @Update("update transaction set cancel_time = #{cancelTime},revoke_status=#{revokeStatus} where id = #{id} and employee_id = #{employeeId}")
    Integer cancelTransaction(Transaction transaction);

    /**
     * 更新事务记录
     * @param transaction 更新的内容
     * @return 更新结果
     */
//    @Update("update transaction set type = #{type}, start_time = #{startTime}, end_time = #{endTime} ,transaction.postponed_time=#{postponeTime}, extension_time=#{extensionTime}, extension_status=#{extensionStatus} where id = #{id} ")
    Integer updateTransaction(Transaction transaction);

    /**
     * 修改请假原因
     * @param id 事务id
     * @param reason 请假原因
     * @param employeeId 员工id
     * @return Integer 1成功，0失败
     */
    @Update("update transaction set reason = #{reason} where id = #{id} and employee_id = #{employeeId} and approval_status = 0")
    Integer updateTransactionReason(Integer id, String reason, String employeeId);

    /**
     * 获取所有考勤记录
     * @param deptId 部门id
     * @param deptType 部门类型
     * @return 所有考勤记录
     */
    List<SetCheckInTimeDTO> getAllRecords(Integer deptId, Integer deptType);

    /**
     * 按月查询考勤记录
     * @param employeeId 员工id
     * @param lastYearMonth 上个月
     * @return 考勤记录
     */
    @Select("select * from emp_sign where employee_id = #{employeeId} and DATE_FORMAT(check_in_date,'%Y-%m') = #{lastYearMonth}")
    List<EmpSign> countAttendanceByMonth(String employeeId, LocalDate lastYearMonth);

    /**
     * 插入考勤统计记录
     * @param attendanceStatistics1 考勤统计记录
     * @return Integer 1成功，0失败
     */
    @Insert("insert into attendance_statistics(employee_id, `year_month`, late_count, leave_early_count, absent_days, attendance_days, leave_days, working_time, over_time) values (#{employeeId}, #{yearMonth}, #{lateCount}, #{leaveEarlyCount}, #{absentDays}, #{attendanceDays}, #{leaveDays}, #{workingTime}, #{overTime})")
    Integer insertAttendanceStatistics(AttendanceStatistics attendanceStatistics1);

    /**
     * 获取所有考勤统计信息
     * @param employeeIds 员工工号
     * @param yearMonth 年月
     * @return 考勤统计信息
     */
    List<AttendanceStatistics> getAllAttendanceStatistics(List<String> employeeIds, String yearMonth);

    /**
     * 员工个人当天考勤记录
     * @param employeeId 员工id
     * @param now 当前时间
     * @return 个人考勤记录
     */
    @Select("select * from emp_sign where employee_id = #{employeeId} and DATE_FORMAT(check_in_date,'%Y-%m-%d') = DATE_FORMAT(#{now},'%Y-%m-%d')")
    EmpSignVO getPersonalRecords(String employeeId, LocalDate now);

    /**
     * 增加员工打卡记录
     * @param employeeId 员工工号
     * @param checkInDate 打卡日期
     */
    @Insert("insert into emp_sign(employee_id, check_in_date) values (#{employeeId}, #{checkInDate})")
    Integer addEmpSign(String employeeId, LocalDate checkInDate);

    /**
     * 删除考勤统计记录
     * @param employeeId 员工工号
     */
    @Delete("delete from attendance_statistics where employee_id = #{employeeId}")
    void deleteStatisticsByEmployeeId(String employeeId);

    /**
     * 删除员工打卡记录
     * @param employeeId 员工工号
     */
    @Delete("delete from emp_sign where employee_id = #{employeeId}")
    void deleteEmpSignByEmployeeId(String employeeId);

    /**
     * 删除员工的事务记录
     * @param employeeId 员工工号
     */
    @Delete("delete from transaction where employee_id = #{employeeId}")
    void deleteTransactionByEmployeeId(String employeeId);
}
